/*
* ECARX Technology Limited is the owner of the copyright and the trade secret of this software.
* Without permission, no one has the right to obtain, disclose or use this software in any way.
*/

package ecarx.xsf.notificationcenter.utils;

import android.Manifest;
import android.annotation.SuppressLint;
import android.app.NotificationManager;
import android.content.ComponentName;
import android.content.Context;
import android.os.Build;
import android.provider.Settings;
import androidx.annotation.RequiresPermission;
import android.text.TextUtils;
import android.util.Log;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashSet;


/**
 * Date    :  2018/11/15 3:42 PM
 * Content :  通知权限设置
 */
public class NotificationAccess {

    private static final String TAG = "NotificationAccess";

    public static final String ENABLED_NOTIFICATION_LISTENERS = "enabled_notification_listeners";

    private static final HashSet<ComponentName> mEnabledListeners = new HashSet<>();


    @RequiresPermission(allOf = {Manifest.permission.WRITE_SETTINGS, Manifest.permission.WRITE_SECURE_SETTINGS})
    public static void enableNotificationAccess(Context context, String packageName, String serviceName) {

        if (isAccessibilityEnabled(context)) {
            Log.d(TAG, "enableNotificationAccess: the accessibility has been enabled");
            return;
        }

        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.O) {
            NotificationManager manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
            try {
                @SuppressLint("SoonBlockedPrivateApi") Method m_setNotificationListenerAccessGranted = manager.getClass()
                        .getDeclaredMethod("setNotificationListenerAccessGranted", ComponentName.class, boolean.class);
                m_setNotificationListenerAccessGranted.setAccessible(true);
                m_setNotificationListenerAccessGranted.invoke(manager, new ComponentName(packageName, serviceName), true);
            } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
                e.printStackTrace();
            }
        } else {

            loadEnabledListener(context);
            mEnabledListeners.add(new ComponentName(packageName, serviceName));
            StringBuilder stringBuilder = null;
            for (final ComponentName componentName : mEnabledListeners) {
                if (stringBuilder == null) {
                    stringBuilder = new StringBuilder();
                } else {
                    stringBuilder.append(":");
                }
                stringBuilder.append(componentName.flattenToShortString());
            }
            Settings.Secure.putString(context.getContentResolver(),
                    ENABLED_NOTIFICATION_LISTENERS, stringBuilder != null ? stringBuilder.toString() : "");
        }

    }

    /**
     * 判断当前应用是否开启NotificationListener监听权限
     *
     */
    private static boolean isAccessibilityEnabled(Context context) {

        String notificationList = Settings.Secure.getString(context.getContentResolver(), ENABLED_NOTIFICATION_LISTENERS);
        if (!TextUtils.isEmpty(notificationList)) {
            final String[] names = notificationList.split(":");
            for (final String name : names) {
                ComponentName componentName = ComponentName.unflattenFromString(name);
                if (componentName != null) {
                    if (TextUtils.equals(componentName.getPackageName(), context.getPackageName())) {
                        return true;
                    }
                }
            }
        }

        return false;
    }

    /**
     * 获取所有开启NotificationListener监听权限的组件
     *
     */
    private static void loadEnabledListener(Context context) {
        mEnabledListeners.clear();
        String notificationList = Settings.Secure.getString(context.getContentResolver(), ENABLED_NOTIFICATION_LISTENERS);
        if (!TextUtils.isEmpty(notificationList)) {
            final String[] names = notificationList.split(":");
            for (final String name : names) {
                ComponentName componentName = ComponentName.unflattenFromString(name);
                if (componentName != null) {
                    mEnabledListeners.add(componentName);
                }
            }
        }
    }

}
